import { Type } from '@angular/core';

/**
 * 属性类型
 */
export enum PropertyType {
    /** 字符串 */
    string = 'string',

    /** 布尔，下拉选择 */
    boolean = 'boolean',

    /** 数字 */
    number = 'number',

    /** 下拉选择：单选 */
    select = 'select',

    /** 已废弃，请使用editableSelect */
    boolOrExp = 'boolOrExp',

    /** 可编辑的下拉选择：单选，并且可编辑 */
    editableSelect = 'editableSelect',

    /** 下拉多选 */
    multiSelect = 'multiSelect',

    /** 日期 */
    date = 'date',

    /** 日期时间 */
    datetime = 'datetime',

    /** 模态窗，自定义组件 */
    modal = 'modal',

    /** 级联 */
    cascade = 'cascade',

    /** 自定义组件 */
    custom = 'custom',

    /** 多功能属性编辑器，支持常量、变量、自定义、表达式等场景 */
    unity = 'unity',

    /** 事件编辑器集成，支持导入命令、参数编辑等场景 */
    events = 'events',

    /** 开关类编辑器，适用于布尔值属性 */
    switch = 'switch',

    /** 多语言输入框 */
    multiLanguage = 'multiLanguage'
}


/**
 * 属性分类实体
 */
export class ElementPropertyConfig {
    /**
     * 分类ID
     */
    categoryId: string;

    /**
     * 分类显示的名称
     */
    categoryName: string;

    /**
     * 分类是否隐藏，默认false
     */
    hide?= false;

    /**
     * 是否隐藏分类标题
     */
    hideTitle?= false;

    /**
     * 分类下的属性配置
     */
    properties: PropertyEntity[];

    /**
     * 是否启用级联特性，默认false
     */
    enableCascade?= false;

    /**
     * 属性值：分类启用级联特性时必填
     */
    propertyData?: any;

    /**
     * 父级属性ID：分类启用级联特性时必填
     */
    parentPropertyID?: string;

    /**
     * 属性关联关系，用于属性变更后修改其他属性配置或属性值
     */
    setPropertyRelates?: (changeObject, propertyData, parameters?) => void;

    /**
     * 分类以标签页展示时，标签页的ID。若只需平铺展示，则不需要传入。
     */
    tabId?: string;

    /**
     * 分类以标签页展示时，标签页的名称。若只需平铺展示，则不需要传入。
     */
    tabName?: string;
}



/**
 * 属性实体
 */
export class PropertyEntity {
    /**
     * 属性ID
     */
    propertyID?: string;

    /**
     * 属性显示的名称
     */
    //事件编辑器集成
    propertyName?: string;

    /**
     * 属性的类型
     */
    propertyType: PropertyType | any;

    /**
     * 属性描述
     */
    description?: string;

    /**
     * 属性的默认值
     */
    defaultValue?: any;

    /**
     * 是否只读，默认false
     */
    readonly?= false;

    /**
     * 是否可见，默认true
     */
    visible?= true;

    /**
     * 最小值
     */
    min?: any;

    /**
     * 最大值
     */
    max?: any;

    /**
     * 数字类型属性的小数位数
     */
    decimals?: number;

    /**
     * 是否大数字
     */
    isBigNumber?= false;

    /**
     * 属性改变后是否需要刷新整个面板：用于更改其他分类下的属性
     */
    refreshPanelAfterChanged?= false;

    /**
     * 下拉框的枚举值
     */
    iterator?: KeyMap[];

    /**
     * 下拉多选类型：属性值的类型：string(多值以逗号分隔)/array(多值组装成数组)
     */
    multiSelectDataType?= 'string';

    /**
     * 文本控件限制输入的字符，支持字符和正则表达式
     */
    notAllowedChars?: any[];

    /**
     * 级联属性配置
     */
    cascadeConfig?: PropertyEntity[];

    /**
     * 级联属性是否默认收起
     */
    isExpand?= false;

    /**
     * 是否隐藏级联属性的头部
     */
    hideCascadeTitle?= false;

    /**
     * 级联属性的汇总信息
     */
    cascadeConverter?: TypeConverter;

    /**
     * 模态框属性自定义编辑器
     */
    editor?: Type<any>;

    /**
     * 模态框属性自定义编辑器参数
     */
    editorParams?: any;

    /**
     *  模态框属性值转换器
     */
    converter?: TypeConverter;

    /**
     * 模态框属性是否展示清除图标
     */
    showClearButton?= false;

    //事件编辑器集成
    /** 内置构件显示的命令列表 */
    internalCommandList?: any;
    /** 内置构件显示的命令列表 */
    viewModel?: any;
    /** 内置构件显示的命令列表 */
    events?: any;
    /** 已绑定的事件 */
    boundEventsList?: any;
    isAddControllerMethod?: boolean;

    /**
     * 点击清除按钮后的方法，参数为清除前的属性值
     */
    afterClickClearButton?(value: any): void;

    /**
     * 打开模态框前的方法，一般用于校验逻辑，返回值中result=true，则进一步打开模态框，result=false则提示message内容，并不再打开模态框。
     */
    beforeOpenModal?(): BeforeOpenModalResult {
        return new BeforeOpenModalResult();
    }

    [propName: string]: any;
}

/**
 * 属性值转换器，返回模态框类属性文本框内的显示内容
 */
export interface TypeConverter {
    convertTo(data: any, params?: any): string; // 由模态框转为属性框中展示的值
}

export interface KeyMap {
    key: any;
    value: any;
}

/**
 * 打开模态框前的方法返回值，result=true，则进一步打开模态框，result=false则提示message内容，并不再打开模态框。
 */
export class BeforeOpenModalResult {
    result: boolean;
    message?: string;
    parameters?: any;
}

/**
 * 属性变更集
 */
export class PropertyChangeObject {
    /**
     * 属性ID
     */
    propertyID: string;

    /**
     * 变更后的属性值
     */
    propertyValue: any;

    /**
     *  属性所在分类ID
     */
    categoryId: string;

    /**
     * 级联属性的父路径，以.分隔
     */
    propertyPath: string;

    /**
     * 级联属性的父属性ID
     */
    parentPropertyID: string;

}
